package com.example.demo.test01;

import org.junit.Before;
import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class demo01 {

    List<String> list = Arrays.asList("a", "b", "c");

    @Test
    public void test01() {
        List<String> list = Arrays.asList("a", "b", "c");
        //创建一个顺序流
        Stream<String> stream = list.stream();
        System.out.println("stream = " + stream);
        //创建一个并行流
        Stream<String> stringStream = list.parallelStream();
        System.out.println("stringStream = " + stringStream);

    }


    @Test
    public void test02() {
        int[] array = {1, 3, 4, 6, 8};

    }


    /**
     * 使用Stream的静态方法,of()、iterater(),generate()
     */
    @Test
    public void test03() {
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
        System.out.println("integerStream = " + integerStream);
        Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
        stream2.forEach(System.out::println);
        System.out.println("===============================================");
        Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
        stream3.forEach(System.out::println);
    }

    /**
     *
     */
    @Before
    public void test04() {
        sayDemo();

    }


    @Test
    public void test05() {
        List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
        //遍历输出符合条件的元素
        list.stream().filter(x -> x > 6).forEach(System.out::println);
        //匹配第一个
        Optional<Integer> first = list.stream().filter(x -> x > 6).findFirst();
        Optional<Integer> findany = list.parallelStream().filter(x -> x > 6).findAny();
        boolean b = list.stream().anyMatch(x -> x < 6);
        System.out.println("first = " + first.get());
        System.out.println("匹配第一个值" + findany.get());
        System.out.println("是否存在大于6的值" + b);
    }


    @Test
    public void StreamTest() {
        List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
        Stream<Integer> stream1 = list.stream();
        stream1.filter(x -> x > 7).forEach(System.out::println);
    }


    public List<Person> sayDemo() {
        List<Person> people = new ArrayList<>();
        people.add(new Person("tom1", 8900, 18, "male", "New Yourk"));
        people.add(new Person("Jack", 7000, 20, "woman", "New Yourk"));
        people.add(new Person("Lily", 6900, 21, "male", "Washington"));
        people.add(new Person("anni", 4900, 39, "woman", "New Yourk"));
        people.add(new Person("tom", 7900, 29, "male", "New Yourk"));
        people.add(new Person("tom", 5900, 19, "woman", "New Yourk"));
        return people;
    }


    @Test
    public void test06() {
        List<Person> people = sayDemo();
        List<String> collect = people.stream().filter(x -> x.getSalary() > 8000).map(Person::getName).collect(Collectors.toList());
        System.out.println("collect = " + collect);
    }


    @Test
    public void test07(){
        List<String> list = Arrays.asList("adnm", "admmt", "pot", "xbangd", "weoujgsd");
        Optional<String> max = list.stream().max(Comparator.comparing(String::length));
        System.out.println("max.get() = " + max.get());
    }



    @Test
    public  void   test08(){
        List<Integer> list = Arrays.asList(7, 6, 9, 4, 11, 6);
        Optional<Integer> max = list.stream().max(Integer::compareTo);
        System.out.println(max.get()+"==========================");

        Optional<Integer> max1 = list.stream().max(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        });
        System.out.println("自然排序最大值"+max.get());
        System.out.println("自然排序最大值"+max1.get());
    }



    @Test
    public  void  test09(){
        List<Person> people = sayDemo();
        Optional<Person> max = people.stream().max(Comparator.comparingInt(Person::getSalary));
        System.out.println("员工工资最大的值"+max.get().getSalary());
    }


    /**
     * Integer集合中大于6的元素的个数
     */
    @Test
    public void  test10(){
        List<Integer> integers = Arrays.asList(7, 6, 8, 11, 13, 19);
        long count = integers.stream().filter(x -> x > 8).count();
        System.out.println("count+List中大于6的元素个数" + count);
    }


    @Test
    public  void  test11(){
        String[] strArr = {"abcd", "bcdd", "defde", "fTr"};
        List<String> collect = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());
        System.out.println("collect = " + collect);

        List<Integer> integers = Arrays.asList(1, 3, 4, 5, 6, 9, 11);
        List<Integer> collect1 = integers.stream().map(x -> x + 3).collect(Collectors.toList());
        System.out.println("collect1 = " + collect1);
    }


    @Test
    public  void   test12(){
      // List<Person> people = new ArrayList<>();
        List<Person> peopleList = sayDemo();
        List<List<Person>> collect = peopleList.stream().map(person -> {
            Person person1 = new Person(person.getName(), 0, 0, null, null);
            person1.setSalary(person.getSalary() + 10000);
            return peopleList;
        }).collect(Collectors.toList());
        System.out.println("第一次改动"+peopleList.get(0).getName());
    }


    @Test
    public  void  test13(){
        List<Person> people = sayDemo();
        //求工资之和的方式
        Optional<Integer> reduce = people.stream().map(Person::getSalary).reduce(Integer::sum);
        //求工资之和的方式2
        Integer reduce1 = people.stream().reduce(0, (sum, p) -> sum += p.getSalary(), (sum1, sum2) -> sum1 + sum2);

        //求最高工资的方式2:
        Integer reduce2 = people.stream().reduce(0, (sum, p) -> sum += p.getSalary(), Integer::sum);
    }


    @Test
    public  void   streamTest(){
        List<Person> peopleList = sayDemo();
        Set<Person> collect = peopleList.stream().collect(Collectors.toSet());
        System.out.println("collect = " + collect);
        //q求总数
       long count =  peopleList.stream().collect(Collectors.counting());
       //求平均工资
        Double average = peopleList.stream().collect(Collectors.averagingDouble(Person::getSalary));
        //求最高工资
        Optional<Integer> max = peopleList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
        //求工资之和
        Integer sum = peopleList.stream().collect(Collectors.summingInt(Person::getSalary));
        //一次性统计所有的信息
        DoubleSummaryStatistics collect1 = peopleList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
        System.out.println("max = " + max);
        System.out.println("count = " + count);
        System.out.println("average = " + average);
        System.out.println("sum = " + sum);
        System.out.println("collect1 = " + collect1);
    }


    @Test
    public  void   test14(){
        List<Person> peopleList = sayDemo();
        String collect = peopleList.stream().map(p -> p.getName()).collect(Collectors.joining(","));
        System.out.println("所有员工的姓名 : " + collect);

        List<String> strings = Arrays.asList("A", "B", "C");
        String string = strings.stream().collect(Collectors.joining("-"));
        System.out.println("string = " + string);
    }


    /**
     * 递归(reducing)
     * Collectors类提供了reducing方法,相比较Stream
     */
    @Test
    public  void test15(){
        List<Person> peopleList = sayDemo();
        //每个员工减去起征点后的薪酬之和
        Integer sum = peopleList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j - 5000)));
        System.out.println("sum = " + sum);
        //Stream的redice
        Optional<Integer> reduce = peopleList.stream().map(Person::getSalary).reduce(Integer::sum);
        System.out.println("reduce.get() = " + reduce.get());
    }


    @Test
    public  void   StreamTest16(){
        List<Person> peopleList = sayDemo();
        Stream<String> stringStream = peopleList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName);
        List<String> collect = stringStream.collect(Collectors.toList());
        System.out.println("collect = " + collect);

        Integer collect1 = peopleList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j - 5000)));
        System.out.println("collect1 = " + collect1);

        Optional<Integer> reduce = peopleList.stream().map(Person::getSalary).reduce(Integer::sum);
        System.out.println("reduce = " + reduce.get());
    }


    @Test
    public  void  test17(){
        List<Person> peopleList = sayDemo();
        //按照工资升序排序(自然排序)
        Stream<String> stringStream = peopleList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName);
    }


    @Test
    public  void  StreamTest17(){
        String[] arr1 = {"a","b","c","d"};
        String[] arr2 = {"d","e","f","g"};
        Stream<String> stream1 = Stream.of(arr1);
        Stream<String> stream2 = Stream.of(arr2);
        //concat:合并两个流distinct:取重
        List<String> collect = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
        System.out.println("collect = " + collect);
        //limit:限制从流中获得当前的n个数据
        List<Integer> collect1 = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
        System.out.println("collect1 = " + collect1);
        //skip:跳过前n个数据
        List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
        System.out.println("collect2 = " + collect2);
    }


    @Test
    public  void  test18(){
        List<Person> peopleList = sayDemo();
        //升序排序
        Stream<String> stream = peopleList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName);
        List<String> collect = stream.collect(Collectors.toList());
        System.out.println("collect = " + collect);
        //按照工资在按照年龄升序排序
        Stream<String> stream1 = peopleList.stream().sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName);
        List<String> collect1 = stream1.collect(Collectors.toList());
        System.out.println("collect1 = " + collect1);

        //先按照工资在在那好年龄自定义降序
        List<String> newList4 = peopleList.stream().sorted((p1, p2) -> {
            if (p1.getSalary() == p2.getSalary()) {
                return p2.getAge() - p1.getAge();
            } else {
                return p2.getSalary() - p1.getSalary();
            }
        }).map(Person::getName).collect(Collectors.toList());
        System.out.println("先按照工资在按照年级自定义降序排序"+newList4);
    }


    @Test
    public  void  test19(){
        List<Person> peopleList = sayDemo();
        //减去税收的总和
        Integer sum = peopleList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j) - 5000));
        System.out.println("collect = " + sum);
        //Stream的reduce
        Optional<Integer> reduce = peopleList.stream().map(Person::getSalary).reduce(Integer::sum);
        System.out.println("reduce.get() = " + reduce.get());
        //Stream的reduce
        Optional<Integer> reduce1 = peopleList.stream().map(Person::getSalary).reduce(Integer::sum);
        System.out.println("reduce1.get() = " + reduce1.get());
    }


    @Test
    public  void   test20(){
        List<Person> peopleList = sayDemo();
        String collect = peopleList.stream().map(p -> p.getName()).collect(Collectors.joining(","));
        System.out.println("collect = " + collect);

        List<String> list = Arrays.asList("A", "B", "C");
        String string = list.stream().collect(Collectors.joining("-"));
        System.out.println("string = " + string);
    }


    @Test
    public  void  test21(){
        List<Person> peopleList = sayDemo();
        //将员工按照性别分组
        Map<Boolean, List<Person>> part = peopleList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
        System.out.println("part = " + part);
        //将员工按照性别分组,在按照地区分组
        Map<String, List<Person>> collect = peopleList.stream().collect(Collectors.groupingBy(Person::getSex));
        List<Person> collect1 = peopleList.stream().collect(Collectors.toList());
    }



    @Test
    public  void  test22(){
        List<Person> peopleList = sayDemo();
        List<Integer> list = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20);
        List<Integer> lietNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
        System.out.println("lietNew = " + lietNew);
        Set<Integer> set = lietNew.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
        System.out.println("set = " + set);

    }

    @Test
    public  void  test23(){
        List<Person> peopleList = sayDemo();
        //求工资之和的方式
        Optional<Integer> reduce = peopleList.stream().map(Person::getSalary).reduce(Integer::sum);
        System.out.println("reduce = " + reduce);
        //求工资之和的方式
        Integer reduce1 = peopleList.stream().reduce(0, (sum, p) -> sum += p.getSalary(), (sum1, sum2) -> sum1 + sum2);
        System.out.println("reduce1 = " + reduce1);
        //求工资之和方式3
        Integer reduce2 = peopleList.stream().reduce(0, (sum, p) -> sum += p.getSalary(), Integer::sum);
        System.out.println("reduce2 = " + reduce2);

        //求工资之和方式1:
        Integer reduce3 = peopleList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(), Integer::max);
        System.out.println("reduce3 = " + reduce3);
        //求最高工资的方式2:
        Integer maxSalary2 = peopleList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
                (max1, max2) -> max1 > max2 ? max1 : max2);
        System.out.println("maxSalary2 = " + maxSalary2);
    }


    @Test
    public  void   StreamTest04(){
        List<Person> peopleList = sayDemo();

        //求总数
        Long collect = peopleList.stream().collect(Collectors.counting());
        System.out.println("collect = " + collect);

        //求平均数
        Double collect1 = peopleList.stream().collect(Collectors.averagingDouble(Person::getSalary));
        System.out.println("collect1 = " + collect1);

        //求最高工资
        Optional<Integer> max = peopleList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compareTo));
        System.out.println("max = " + max);


        //求平均工资
        Double collect2 = peopleList.stream().collect(Collectors.averagingDouble(Person::getSalary));
        System.out.println("collect2 = " + collect2);

    }
}































